package com.ideal.gpt.ability.doccompare;

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiFunction;

import com.ideal.gpt.GptJobConfig;
import com.ideal.gpt.ability.docqa.caller.DocQaCaller;
import com.ideal.gpt.app.local.WordToVector;
import com.lzwork.gpt.utility.caller.GptCallResult;
import com.lzwork.gpt.utility.common.ParserCaller;
import com.lzwork.utility.file.LineContent;
import com.lzwork.utility.pair.StringPair;
import com.lzwork.utility.pair.StringTuple;
import com.lzwork.utility.str.StrUtility;
import com.lzwork.utility.str.similar.JwDistance;
import com.lzwork.web.data.CallResultInfo;

import name.fraser.neil.plaintext.diff_match_patch;
import name.fraser.neil.plaintext.diff_match_patch.Diff;
import name.fraser.neil.plaintext.diff_match_patch.Operation;

/**
 * @author LiZheng
 * @date 2023年10月19日 上午9:53:22
 */

public class DocCompare
{
	public static class DiffInfo extends StringTuple
	{
		public DiffInfo(String v1, String v2, String v3)
		{
			super(v1, v2, v3);
		}

		public String combineDiff()
		{
			return first();
		}

		public String sourceDiff()
		{
			return second();
		}

		public String targetDiff()
		{
			return third();
		}
	}

	static String spanInsertCss = "background:#b6ffb6;text-decoration:underline;";
	static String spanDeleteCss = "background:#ffb6b6;text-decoration:line-through;";
	static String boldCss = "font-weight:bold;";

	static void appendDiff(StringBuilder sb, Diff diff, Operation opFilter, boolean bold)
	{
		Operation op = diff.operation;

		if (op != Operation.EQUAL && opFilter != Operation.EQUAL)
		{
			if (opFilter != op)
				return;
		}

		String str = diff.text;
		str = str.replace("\n", "<br>");

		sb.append("<span style='");

		if (bold)
			sb.append(boldCss);

		if (op == Operation.DELETE)
		{
			sb.append(spanDeleteCss);
		} else if (op == Operation.INSERT)
		{
			sb.append(spanInsertCss);
		}

		sb.append("'>");
		sb.append(str);
		sb.append("</span>");
	}

	public static float getVectorSimulate(String first, String second)
	{
		String url = GptJobConfig.getProp("embed_server") + "/cosSimStr";

		WordToVector parser = new WordToVector(url);

		return parser.getVecCosSim(first, second);
	}

	public static float getDistantSimulate(String first, String second)
	{
		return JwDistance.getDistance(first, second);
	}

	public static DiffInfo getCompareResult(StringPair sp, boolean bold)
	{
		return getCompareResult(sp.first(), sp.second(), bold);
	}

	public static DiffInfo getCompareResult(String inputStr, String targetStr, boolean bold)
	{
		diff_match_patch dmp = new diff_match_patch();
		LinkedList<Diff> diffList = dmp.diff_main(inputStr, targetStr);
		dmp.diff_cleanupSemantic(diffList);

		StringBuilder combineCheck = new StringBuilder();

		StringBuilder inputCheck = new StringBuilder();
		StringBuilder targetCheck = new StringBuilder();

		for (Diff diff : diffList)
		{
			appendDiff(combineCheck, diff, Operation.EQUAL, bold);
			appendDiff(inputCheck, diff, Operation.DELETE, bold);
			appendDiff(targetCheck, diff, Operation.INSERT, bold);
		}

		return new DiffInfo(combineCheck.toString(), inputCheck.toString(), targetCheck.toString());
	}
	
	public static String policyComparePrompt(String first, String second)
	{
		return "这是第一个政策：\n```" + first + "\n```\n这是第二个政策：\n```" + second + "\n```\n对比一下两段政策的区别。";		
	}
	
	public static String commonComparePrompt(String first, String second)
	{
		return "这是第一篇文章：\n```" + first + "\n```\n这是第二篇文章：\n```" + second + "\n```\n对比一下篇文章的区别。";		
	}

	public static CallResultInfo<String> chatCompare(List<String> first, List<String> second, boolean dolog)
	{
		String firstStr = StrUtility.combineString(first, "\n");
		String secondStr = StrUtility.combineString(second, "\n");
		return chatCompare(firstStr, secondStr, dolog);
	}

	public static CallResultInfo<String> chatCompare(String first, String second, boolean dolog)
	{
		return chatCompare(first, second, null, null, dolog);
	}

	public static CallResultInfo<String> chatCompare(String first, String second, ParserCaller caller,
			BiFunction<String, String, String> promptMaker, boolean dolog)
	{
		if (caller == null)
			caller = new DocQaCaller(GptJobConfig.url());
		
		String input = null;
		if (promptMaker != null)
			input = promptMaker.apply(first, second);

		if (input == null)
			input = commonComparePrompt(first, second);

		GptCallResult cr = caller.callChat(input, "Doc compare job", dolog);
		String cost;
		String info;

		if (cr.getException() != null)
		{
			cost = null;
			info = cr.getException().getMessage();
		} else
		{
			cost = cr.getGpuCost();
			info = cr.getResponse();
		}

		return new CallResultInfo<>(cost, info);
	}

	public static void main(String[] args)
	{
		File f1 = new File("V:/12345/政策比对/上海市环城绿带管理办法/old.txt");
		File f2 = new File("V:/12345/政策比对/上海市环城绿带管理办法/new.txt");

		String str1 = LineContent.loadString(f1);
		String str2 = LineContent.loadString(f2);

		StringTuple st = getCompareResult(str1, str2, false);

		System.out.println(st);
	}
}
